<template>
  <div class="talk" @click="handleClickBody">
    <!-- 自定义导航栏 -->
    <gh-navbar id="navbar" :title="lawyer_realname" url="/pages/zixun/zixun" @back="handleBack" />
    <!-- 中间聊天内容 -->
    <scroll-view
      :scroll-top="scrollTop"
      :scroll-y="true"
      :scroll-with-animation="false"
      id="scrollview"
      class="main"
      :style="mainStyle"
      @scrolltolower="handleScrollToLower"
      @scrolltoupper="handleScrollToUpper"
      @scroll="handleScroll"
    >
      <div id="container">
        <div class="item" v-for="(item, index) in messages" :class="item.arr.class" :key="index">
          <div class="time" v-if="item.time" >{{item.time}}</div>
          <div class="tip" v-if="item.arr.identity == 'system'">{{item.arr.msg}}</div>
          <div class="content-box">
            <div class="item-content">
              <div class="left" v-if="item.arr.identity == 'seller'">
                <image :src="item.arr.avatar" class="avatar"></image>
                <!-- 发送纯文本 -->
                <text class="message" space="nbsp" v-if="item.arr.type == 'text'">{{item.arr.msg}}</text>
                <!-- 发送文件 -->
                <div
                  class="message file-message"
                  v-else-if="item.arr.type == 'file'"
                  @click="handleDownFile(item)"
                >
                  <div class="file-info">
                    <div>{{item.arr.filename}}</div>
                    <div class="file-size">{{item.arr.fileSize}}</div>
                  </div>
                  <div class="file-icon">
                    <text class="iconfont icon-wenjian"></text>
                  </div>
                </div>
                <!-- 发送图片 -->
                <image v-else class="msg-photo" @click.stop="handlePreview(item.arr.msg)" :src="item.arr.msg" />
              </div>
              <div class="right" v-if="item.arr.identity == 'buyer'">
                <!-- 发送纯文本 -->
                <text class="message" space="nbsp" v-if="item.arr.type == 'text'">{{item.arr.msg}}</text>
                <!-- 发送文件 -->
                <div
                  class="message file-message"
                  v-else-if="item.arr.type == 'file'"
                  @click="handleDownFile(item)"
                >
                  <div class="file-info">
                    <div>{{item.arr.filename}}</div>
                    <div class="file-size">{{item.arr.fileSize}}</div>
                  </div>
                  <div class="file-icon">
                    <text class="iconfont icon-wenjian"></text>
                  </div>
                </div>
                <!-- 发送图片 -->
                <div class="photo-box" v-else>
                  <image class="msg-photo" @click.stop="handlePreview(item.arr.msg)" :src="item.arr.msg" />
                </div>
                <image :src="item.arr.avatar" class="avatar"></image>
              </div>
            </div>
          </div>
        </div>
      </div>
    </scroll-view>
    <!-- 底部输入框 -->
    <div class="footer" id="footer" v-show="orderStatus" :style="'bottom:'+keyboardPadding+'px;'">
      <div class="footer-header" id="footer-header">
        <textarea
          class="input"
          :style="'padding:'+ textareaPadding +'rpx;'"
          @linechange="handleHeightChange"
          :fixed="true"
          cursor-spacing="20"
          :adjust-position="false"
          :show-confirm-bar="false"
          :auto-height="autoHeight"
          :hold-keyboard="true"
          v-model="userInput"
          maxlength="-1"
          @focus="handleFocus"
          @blur="handleBlur"
        />
        <div v-if="userInput.length > 0" class="send" @click.stop="handleAdd">发送</div>
        <div class="icon" @click.stop="handleShow" v-if="userInput.length <= 0">
          <text class="iconfont icon-jia"></text>
        </div>
      </div>

      <div class="util-box" v-show="showUtil">
        <div class="util">
          <div class="photo" @click.stop="handleChooseImg">
            <div class="icon-box">
              <text class="iconfont icon-tupian"></text>
            </div>
            <div class="icon-text">图片</div>
          </div>
          <div class="photo file" @click.stop="handleChooseFile">
            <div class="icon-box">
              <text class="iconfont icon-wenjianjia-"></text>
            </div>
            <div class="icon-text">文件</div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      lawyer_realname: '', // 律师名字
      messages: [], // 消息容器
      userInput: "",
      textareaPadding: 0,
      bottomHeight: 0, // 默认底部内边距
      showUtil: false,
      autoHeight: true,
      textareaAddHeight: 0, // 输入框增加的高度
      lineCount: 0, // 输入框的行数
      subtractHeight: false, // 控制是否减行数，减main的padding-bottom值
      scrollTop: 0,
      old: {
        scrollTop: 0
      },
      scrollViewHeight: 0, // scroll-view组件的高度
      userScorll: false,
      keyboardPadding: 0,
      ghFooterHeight: 0, // footer节点高度
      focusStatus: false, // 输入框是否聚焦
      loadImg: [], // 上传的图片路径数组
      upLoadFilePath: "", // 上传文件之后的网络地址，downFile中使用
      filename: "", // 上传的文件名
      send: true,
      uid: 0, // 用户id
      talkPage: 1, // 聊天记录页码数
      recordLength: 0, //  请求的聊天记录的数组长度
      orderStatus: true, // 订单状态
      connectTimer: 0, // 重连定时器
      upperLoading: false, // 获取聊天记录的节流flag
      room_id: 1430, // 聊天房间id
      platform: '', // 系统 ios android
      reconnection: false,  // 是否重连
      savedFilePath: '', // 文件本地路径
      lastTime: '', // 发送消息的最后时间
    };
  },
  created() {
    let that = this;
    uni.getSystemInfo({
      success: function(res) {
        // 获取屏幕高度
        that.windowHeight = res.windowHeight;
        that.platform = res.platform
        if (res.platform == "ios") {
          that.textareaPadding = 5;
        } else if (res.platform == "android") {
          that.textareaPadding = 25;
        } else {
          that.textareaPadding = 15;
        }
      }
    });
  },
  mounted() {
    let that = this;
    setTimeout(() => {
      // 获取节点信息
      let query = uni.createSelectorQuery().in(this);
      query.select("#scrollview").boundingClientRect();
      query.select("#container").boundingClientRect();
      query.select("#navbar").boundingClientRect();
      query.select("#footer-header").boundingClientRect();
      query.select(".util-box").boundingClientRect();
      that.query = query;
      query.exec(resexec => {
        that.scrollViewHeight = that.windowHeight - resexec[2].height;
        that.ghFooterHeight = resexec[3].height;
        that.bottomHeight = resexec[3].height; // scoll-view的padding-bottom值，footer输入框的高度
        console.log(that.bottomHeight, "mounted");
      });
      that.scrollToBottom();
    }, 500);
  },
  async onShow() {
    const that = this
    // if (this.$store.state.openDoc) {  // true的时候证明是打开文件
    //   return
    // }
    // if (!this.$store.state.loginStatus) {  // false的时候证明是选择图片或文件
    //   return
    // }
    // uni.connectSocket({
    //   url: that.$store.state.wssBaseUrl
    // });
    // 获取当前用户信息
    const res = await this.$gh
      .request("member.info", {
        data: {
          op: "getMember"
        }
      })
      .catch(err => {
        uni.hideLoading();
      });
    this.uid = res.data.list.id;
    this.$store.state.userAvatar = res.data.list.avatar;

    // 测试代码，修改身份
    // this.$store.state.identity = this.uid == 3 ? "seller" : "buyer";

    // 以下是websocket
    
    uni.onSocketOpen(function(res) {
      console.log("WebSocket连接已打开！");
      // 发送用户信息给服务端
      const data = {
        type: 'storage_users',
        uid: that.uid,
        identity: that.$store.state.identity
      }
      that.$store.dispatch("sendMsg", data);
      if(that.platform == 'android'){
        clearInterval(that.connectTimer)
      }else{
        clearTimeout(that.connectTimer)
      }
      // 重连之后登录
      setTimeout(() => {
        console.log(2222);
        // 登录
        let data = {
          type: "login",
          room_id: that.room_id,
          uid: that.uid,
          identity: that.$store.state.identity
        };
        that.$store.dispatch("sendMsg", data);
        // 代表重连了
        that.reconnection = true
        that.talkPage = 1
        // 获取聊天数据
        let talkData = {
          type: "record",
          room_id: that.room_id,
          page: that.talkPage,
          psize: 20
        };
        that.$store.dispatch("sendMsg", talkData);
        uni.hideLoading();
      }, 1000);
    });
    uni.onSocketClose(function(res) {
      console.log('断开了talk');
      if(that.platform == 'android'){
        // 安卓要用setInterval，否则只执行一次重连
        that.connectTimer = setInterval(() => {
          console.log('重连');
          uni.connectSocket({
            url: that.$store.state.wssBaseUrl,
            success(){
              uni.showLoading({
                mask: true,
                title: '拼命重连中...'
              });
            }
          });
        }, 1000)
      }else{
        that.connectTimer = setTimeout(() => {
          console.log('重连');
          uni.connectSocket({
            url: that.$store.state.wssBaseUrl,
            success(){
              uni.showLoading({
                mask: true,
                title: '拼命重连中...'
              });
            }
          });
        }, 1000)
      }
    });
    // 登录
    let data = {
      type: "login",
      room_id: that.room_id,
      uid: this.uid,
      identity: that.$store.state.identity
    };
    // 获取聊天数据
    let talkData = {
      type: "record",
      room_id: that.room_id,
      page: this.talkPage,
      psize: 20
    };
    // if (this.$store.state.openDoc) {  // true的时候证明是打开文件
    //   return
    // }
    // if (!this.$store.state.loginStatus) {  // false的时候证明是选择图片或文件
    //   return
    // }
    // 如果是上传图片，文件，打开文件。就不用执行了，登录会把上一个登录踢出去，即使是同一个手机
    if(this.$store.state.loginStatus && !this.$store.state.openDoc){
      console.log(that.$store.state.loginStatus);
      console.log(454545645);
      if(this.$store.state.preview){
        // 预览图片
        this.$store.commit('setPreview', false)
        return
      }
      this.$store.dispatch("sendMsg", data);
      this.$store.dispatch("sendMsg", talkData);
    }
    uni.onSocketMessage(function(res) {
      let resData = JSON.parse(res.data);
      let type = resData.type;
      // console.log(resData, "talk");
      if (type == "login") {
        console.log(resData, "login");
        that.lawyer_realname = resData.realname
        // 记录身份，卖家是对方，买家是自己
        if (resData.identity == that.$store.state.identity) {
          // 记录自己的id
          that.client_id = resData.client_id;
        }
        // 判断订单状态
        if(resData.order.status == 2){
          that.$store.dispatch('modal', '订单已完成')
          // 交易完成
          that.orderStatus = false
        }
      } else if (type == "say") {
        console.log(resData, "say");
        // 收到对方发来的消息
        if (resData.from_client_id != that.client_id) {
          let { content } = resData;
          that.messages.push(content);
          that.scrollToBottom();
        }
      } else if (type == "record") {
        if(resData.list.length === 0) {
          uni.hideLoading();
          return
        }
        console.log(resData);
        // 聊天记录
        that.recordLength = resData.list.length;
        // 如果不是重连，那么请求回来的数据和之前的拼接。
        let arr = that.reconnection || that.$store.state.openDoc ? resData.list : resData.list.concat(that.messages);
        console.log(arr);
        that.messages = arr;
        if(that.reconnection || that.$store.state.openDoc){
          // 只要数据回来了，就不是重连状态
          that.reconnection = false
          that.$store.state.openDoc = false
          console.log(333);
          that.scrollToBottom()
          return
        }
        if(that.talkPage == 1) {
          uni.hideLoading();
          that.scrollToBottom()
          return
        }
        
        // 滚动
        setTimeout(() => {
          // 获取节点信息
          let query = uni.createSelectorQuery().in(that);
          query.selectAll(".record_" + that.talkPage).boundingClientRect();
          query.exec(resexec => {
            // let height =  0
            // resexec[0].forEach((element) => {
            //   height += element.height
            // })
            const height = resexec[0][resexec[0].length - 1].top || 0   
            console.log(resexec);
            console.log(height);
            that.scrollTop = height
            uni.hideLoading();
            that.upperLoading = false
          });
        }, 100);
      }else if(type == 'kickout'){
        uni.showToast({
          icon: 'none',
          title: '别调皮，好好coding去！',
          mask: true,
          duration: 2000
        });
        setTimeout(() => {
          uni.switchTab({
              url: '/pages/zixun/zixun'
          });
        },2000)
      }else if(type == 'extrusion_line'){
        uni.showToast({
          icon: 'none',
          title: '该账号已在另一设备登录！',
          mask: true,
          duration: 2000
        });
        setTimeout(() => {
          uni.switchTab({
              url: '/pages/zixun/zixun'
          });
        },2000)
      }
    });
  },
  async onLoad(e) {
    this.room_id = e.id
    const that = this
    // this.identity = e.id == 0 ? "seller" : "buyer";
    this.lastTime = uni.getStorageSync('lastTime') || 0;
    console.log(this.lastTime);
    uni.onKeyboardHeightChange(res => {
      if(res.height == 0){
        that.focusStatus = false;
        that.bottomHeight -= that.keyboardPadding; // scoll-view的padding-bottom值，footer输入框的高度
        that.keyboardPadding = 0;
      }
    })
  },
  onUnload(){
    // 物理返回键，或者手势返回上一页
    if(this.$store.state.openDoc) return
    if (this.$store.state.loginStatus) {
      // 记录上次最后发送消息的时间
      console.log(this.lastTime);
      uni.setStorageSync('lastTime', this.lastTime)
      // 返回，断开连接
      let data = {
        type: "logout"
      };
      this.$store.dispatch("sendMsg", data);
    }
  },
  watch: {
    "old.scrollTop"(newVal, oldVal) {
      // 判断用户下拉，不滚动底部  this.userScorll = true 代表用户下拉
      newVal < oldVal ? (this.userScorll = true) : (this.userScorll = false);
    },
    lineCount(newVal, oldVal) {
      console.log(newVal, oldVal);
      // 判断是删除行数还是增加行数
      newVal < oldVal
        ? (this.subtractHeight = true)
        : (this.subtractHeight = false);
      if (newVal == 1 && oldVal == 2) {
        this.subtractHeight = true;
      }
    }
  },
  computed: {
    mainStyle() {
      return `height:${this.scrollViewHeight}px;padding-bottom:${this.bottomHeight}px;margin-bottom:${this.keyboardPadding}px;`;
      // return `height:${this.scrollViewHeight}px;padding-bottom: 0;`;
    }
  },
  methods: {
    handleScrollToUpper() {
      if (this.recordLength < 20) return;
      if (this.upperLoading) return
      this.upperLoading = true
      uni.showLoading({
        title: '加载中'
      });
      this.talkPage++;
      // 获取聊天数据
      let talkData = {
        type: "record",
        room_id: this.room_id,
        page: this.talkPage,
        psize: 20
      };
      this.$store.dispatch("sendMsg", talkData);
    },
    async handleBack() {
      this.$store.state.loginStatus = true
      this.$store.state.openDoc = false
      // 返回，断开连接
      let data = {
        type: "logout"
      };
      this.$store.dispatch("sendMsg", data);
    },
    async previewFile(item){  // 从item中获取文件网络路径
      const that = this;
      uni.showLoading({
        title: "加载中"
      });
      // 下载文件
      const promise1 = new Promise((resolve, reject) => {
        uni.downloadFile({
          url: item.arr.filePath, 
          success: res => {
            if (res.statusCode === 200) {
              uni.hideLoading();
              that.$store.state.openDoc = true
              resolve(res.tempFilePath);
            } else {
              uni.showToast({
                mask: true,
                icon: "none",
                title: "下载失败",
                duration: 2000
              });
              reject(false);
            }
          }
        });
      });
      const tempFilePath = await promise1;
      uni.openDocument({
        filePath: tempFilePath,
        success: function(res) {
          that.scrollToBottom()
          console.log("打开文档成功");
        }
      });
    },
    async handleDownFile(item) {
      
      const that = this;
      
      uni.showModal({
        title: '温馨提示',
        content: '如要下载文件，需复制链接在浏览器打开！',
        cancelText: '复制链接',
        confirmText: '预览',
        success: function (res) {
          if (res.confirm) {
            that.previewFile(item)
          } else if (res.cancel) {
            uni.setClipboardData({
                data: item.arr.filePath,
                success: function () {
                    uni.showToast({
                      title: '复制成功',
                      duration: 2000
                    });
                }
            });
          }
        }
      });
      
      // 保存文件
      // uni.saveFile({
      //   tempFilePath,
      //   success: function (res) {
      //     var savedFilePath = res.savedFilePath;
      //     console.log(savedFilePath);
      //     // 打开文件
      //     uni.openDocument({
      //       filePath: savedFilePath,
      //       success: function (res) {
      //         console.log('打开文档成功');
      //       }
      //     });
      //   }
      // });
    },
    handleClickBody() {
      this.send = false;
      if (this.showUtil) {
        this.handleShow();
      }
      this.handleBlur();
    },
    // 查看图片
    handlePreview(url) {
      // 防止触发websocket的退出登录
      this.$store.commit("setPreview", true);
      const that = this;
      uni.previewImage({
        current: url,
        urls: [url],
        success(){}
      });
    },
    async handleChooseImg() {
      // 防止触发websocket的退出登录
      this.$store.commit("setStatus", false);
      let that = this;
      // 选择图片
      let tempFilePaths = await this.$gh.chooseImage(9);
      // 循环上传
      tempFilePaths.forEach((element, index) => {
        uni.uploadFile({
          url: that.$store.state.baseUrl + "util.wx_uploader", //仅为示例，非真实的接口地址
          filePath: element,
          name: "file",
          success: async uploadFileRes => {
            const data = JSON.parse(uploadFileRes.data);
            const { filename, url } = data.data.list;
            const msg = url + filename;
            // const content = that.initSendMsg(msg, "img");
            const content = await that.initSendMsg(msg, "img")
            if(!content){
              return
            }
            this.messages.push(content);
            setTimeout(() => {
              this.scrollToBottom();
              // 成功之后把状态改回来
              this.$store.commit("setStatus", true);
            }, 50);
            // that.loadImg.push({ url, filename });
            // uni.showToast({
            //   icon: 'success',
            //   title: '图片上传成功',
            //   duration: 2000
            // });
          },
          fail(err) {
            console.log(err);
          }
        });
      });
    },
    async handleChooseFile() {
      // 防止触发websocket的退出登录
      uni.showLoading({
        title: '加载中'
      });
      this.$store.commit("setStatus", false);
      const res = await this.$gh.chooseFile();
      console.log(res);
      this.upLoadFilePath = res.url;
      this.filename = res.fileName;
      const content = await this.initSendMsg(
        res.url,
        "file",
        res.url,
        res.fileName,
        res.fileSize
      )
      if(!content){
        return
      }
      console.log(content);
      this.messages.push(content);
      uni.hideLoading();
      setTimeout(() => {
        this.scrollToBottom();
        // 成功之后把状态改回来
        this.$store.commit("setStatus", true);
      }, 50);
    },
    initSendMsg(
      msg = this.userInput,
      type = "text",
      filePath = "",
      fileName = "",
      fileSize = ""
    ) {
      // 默认发送文字
      const that = this
      const date = new Date();
      const hour = date.getHours();
      const min = date.getMinutes();
      let time = date.getTime() - this.lastTime >= 1000 * 60 * 5 ? hour + ":" + min : ""; // 大于5分钟显示
      this.lastTime = date.getTime();
      let content = {
        time,
        arr: {
          identity: that.$store.state.identity, // buyer是自己  ， seller是对方
          type, // 值为text的时候代表单纯的文字，img代表图片地址， file代表文件地址
          msg, // 内容。文字或者图片网址
          avatar: that.$store.state.userAvatar, // 头像
          fileSize, // 文件大小
          filename: fileName, // 文件名
          filePath // 文件路径
        }
      };
      let data = {
        type: "say",
        room_id: that.room_id,
        client_id: that.client_id,
        identity: that.$store.state.identity,
        content,
        uid: this.uid
      };
      return new Promise((resolve, reject) => {
        this.$store.dispatch("sendMsg", data).then(resData => {
          resolve(content)
        }).catch((err) => {
          console.log(11);
          uni.showToast({
            icon: 'none',
            title: '网络出现问题，发送失败',
            duration: 2000
          });
          reject(err)
        })
      })
    },
    // 发消息
    async handleAdd() {
      this.send = true;
      // 发文字
      let content = await this.initSendMsg(this.userInput)
      if(!content){
        return
      }
      this.messages.push(content);
      setTimeout(() => {
        this.scrollToBottom();
      }, 50);
      this.autoHeight = true;
      this.userInput = "";
      // 播放提示音
      // const innerAudioContext = uni.createInnerAudioContext();
      // innerAudioContext.autoplay = true;
      // innerAudioContext.src = 'https://img-cdn-qiniu.dcloud.net.cn/uniapp/audio/music.mp3';
    },
    handleBlur() {
      if (this.send) return; // 如果是发送而触发的失去焦点
      uni.hideKeyboard();
      this.focusStatus = false;
      this.bottomHeight -= this.keyboardPadding; // scoll-view的padding-bottom值，footer输入框的高度
      this.keyboardPadding = 0;
    },
    handleFocus(e) {
      // 避免有时候输入时触发到聚焦，重复设置bottomHeight，导致高度错乱
      this.showUtil = false;
      if (this.focusStatus) return;
      this.focusStatus = true;

      // 键盘弹起
      this.keyboardPadding = e.detail.height;
      // 获取焦点，滚动到底
      setTimeout(() => {
        this.query.exec(resexec => {
          let height = e.detail.height + resexec[3].height; // footer的高度，有可能输入框中有内容，所以获取实际高度
          this.userScorll = false;
          this.bottomHeight = height;
          this.scrollToBottom();
        });
      }, 50);
    },
    handleScrollToLower(e) {
      // 滚动到底部的时候，代表用户没有下拉看以前的信息，接受信息滚动到底
      this.userScorll = false;
    },
    handleScroll(e) {
      this.old.scrollTop = e.detail.scrollTop;
    },
    async showLuoji() {
      // 正常逻辑
      // 如果是聚焦，然后点击的加号展示util，隐藏键盘
      if (this.keyboardPadding != 0) {
        this.bottomHeight -= this.keyboardPadding;
        uni.hideKeyboard();
        // footer的定位距离受键盘高度影响
        this.keyboardPadding = 0;
      }
      this.focusStatus = false;
      this.userScorll = false;
      const res = await this.scrollToBottom();
      this.showUtil = !this.showUtil;
      // show
      if (this.showUtil) {
        // 已经知道高度
        if (this.ghUtilHeight) {
          let height = this.ghFooterHeight + this.utilHeight; // footer的高度
          this.bottomHeight = height;
          this.scrollToBottom();
        } else {
          // 第一次获取高度
          setTimeout(() => {
            this.query.exec(resexec => {
              this.utilHeight = resexec[4].height; // util-box的高度
              this.ghUtilHeight = resexec[4].height; // 记录已经知道的util-box的高度
              let height = resexec[3].height + resexec[4].height; // footer的高度
              this.bottomHeight = height;
              this.scrollToBottom();
            });
          }, 50);
        }
      } else {
        // hide
        let height = this.ghFooterHeight; // footer的高度
        this.bottomHeight = height;
        this.scrollToBottom();
      }
    },
    handleShow() {
      // 这个情况是为了解决输入框获取焦点的时候，点击+号展开上传图片，传输文件的菜单栏。
      // 这个时候先触发了+号的点击事件，后在执行输入框失去焦点事件
      // 延迟执行逻辑
      if (this.focusStatus) {
        setTimeout(() => {
          this.showLuoji();
        }, 100);
      } else {
        this.showLuoji();
      }
    },
    handleHeightChange(e) {
      // 记录行数
      this.lineCount = e.detail.lineCount;
      // 输入框增加的高度
      this.textareaAddHeight = e.detail.height / e.detail.lineCount;
      setTimeout(() => {
        // 延时处理，为了watch先更新数据，判断是增加行数还是删除行数

        if (e.detail.lineCount == 3) {
          if (this.subtractHeight) {
            // 如果从4行 - 到3行，不要减padding的高度。因为都是3行，无论增加还是减都保持3行时应该有的高度
            // 比如2加到3时，padding是88px，则4减到3时，padding也要是88px。所以不用设置this.bottomHeight
            this.scrollToBottom();
          } else {
            // 增加输入
            this.autoHeight = false; // textarea限制最多输入3行
            this.bottomHeight += this.textareaAddHeight;
            this.scrollToBottom();
          }
        } else if (e.detail.lineCount > 3) {
          // 超过3行什么都不管
        } else if (e.detail.lineCount < 3 && !this.subtractHeight) {
          try {
            // 初始化页面会触发，此时this.query还没有
            // 小于3行,并且是输入增加文字(增加行数)
            this.autoHeight = true;
            // 滚动到底
            this.scrollToBottom();
            if (this.lineCount == 1) {
              // ios, 输入会触发这个行高改变事件
              return;
            }
            this.bottomHeight += this.textareaAddHeight;
          } catch (error) {}
        } else if (e.detail.lineCount < 3 && this.subtractHeight) {
          // 小于3行,并且是删除文字(减少行数)
          this.autoHeight = true;
          this.bottomHeight -= this.textareaAddHeight;
        }
      }, 500);
    },
    scrollToBottom() {
      const that = this;
      return new Promise((resolve, reject) => {
        if (this.userScorll) {
          reject("用户在滑动");
        }
        that.scrollTop = that.old.scrollTop;
        try {
          this.query.exec(res => {
            // let top = that.windowHeight + res[2].height + res[3].height
            let top =
              res[0].height +
              res[1].height +
              res[2].height +
              res[3].height +
              res[4].height;
            this.$nextTick(function() {
              that.scrollTop = top;
              that.userScorll = false;
              resolve(true);
            });
          });
        } catch (error) {
          reject();
        }
      });
    }
  }
};
</script>
<style lang='less' scoped>
@import url("../common/util.less");
.talk {
  .header {
    position: fixed;
    width: 100%;
    .status-bar {
      // height: var(--status-bar-height);
      width: 100%;
      background-color: #bfa;
    }

    .navigationbar {
      .flex();
      width: 100%;
      color: #000;
      font-size: 36rpx;
      background-color: red;
      .back {
        transform: rotate(180deg);
        padding: 10rpx;
        .iconfont {
          color: #000;
          font-size: 36rpx;
        }
      }
    }
  }

  .main {
    height: 100%;
    box-sizing: border-box;
    margin-top: 20rpx;
    .item {
      .time {
        font-size: 24rpx;
        color: @font-color;
        padding: 0 0 25rpx;
        text-align: center;
      }
      .tip {
        text-align: center;
        font-size: 26rpx;
        color: @font-color;
      }
      .content-box {
        .item-content {
          padding: 28rpx 20rpx;
          margin-bottom: 28rpx;
          font-size: 30rpx;
          color: @deep-color;
          border-radius: 5rpx;
          .msg-photo {
            width: 150rpx;
            height: 150rpx;
            margin: 0 25rpx;
          }
          .photo-box {
            flex: 1;
            text-align: right;
          }
          .left {
            .flex();
            width: 80%;
            .message {
              max-width: calc(100% - 184rpx);
              overflow: hidden;
              border-top-left-radius: 44rpx;
              border-top-right-radius: 44rpx;
              border-bottom-right-radius: 44rpx;
              background-color: #eaf0fe;
              margin-left: 10rpx;
              padding: 27rpx 42rpx;
              word-break:break-all;
            }
            .file-message {
              .flex();
              .file-info {
                flex: 1;
                .file-size {
                  font-size: 24rpx;
                  margin-top: 5rpx;
                  color: #97a0c5;
                }
              }
              .file-icon {
                width: 25%;
                text-align: center;
                .icon-wenjian {
                  font-size: 80rpx;
                  color: @theme-color;
                }
              }
            }
          }
          .right {
            .flex();
            justify-content: flex-end;
            width: 80%;
            margin-left: 20%;
            .message {
              max-width: calc(100% - 184rpx);
              overflow: hidden;
              border-top-left-radius: 44rpx;
              border-top-right-radius: 44rpx;
              border-bottom-left-radius: 44rpx;
              background-color: @theme-color;
              margin-right: 10rpx;
              padding: 27rpx 42rpx;
              color: #fff;
              word-break:break-all;
            }
            .file-message {
              .flex();
              .file-info {
                color: #fff;
                flex: 1;
                .file-size {
                  font-size: 24rpx;
                  margin-top: 5rpx;
                }
              }
              .file-icon {
                width: 25%;
                text-align: center;
                .icon-wenjian {
                  font-size: 80rpx;
                  color: #eaf0fe;
                }
              }
            }
          }
          .avatar {
            width: 90rpx;
            height: 90rpx;
            border-radius: 50%;
          }
        }
      }
    }
  }

  .footer {
    position: fixed;
    bottom: 0;
    left: 0;
    width: 100%;
    z-index: 1;
    .footer-header {
      box-sizing: border-box;
      .gh-between();
      // align-items: flex-end;
      padding: 15rpx 20rpx;
      background-color: #f8f8f8;
      border-top: 1px solid #eee;
      border-bottom: 1px solid #eee;
    }
    .input {
      width: 560rpx;
      padding: 25rpx;
      border: none;
      outline: none;
      background-color: #fff;
      font-size: 32rpx;
      color: #000;
    }
    .send {
      .gh-center();
      width: 125rpx;
      height: 68rpx;
      background-color: @theme-color;
      margin-left: 25rpx;
      color: #fff;
      font-size: 32rpx;
      border-radius: 10rpx;
    }
    .icon {
      flex: 1;
      margin-left: 25rpx;
      .gh-center();
      .iconfont {
        font-size: 50rpx;
        color: #000;
      }
    }
    .util-box {
      .util {
        .flex();
        padding: 60rpx;
        background-color: #f8f8f8;
        .photo {
          margin-right: 55rpx;
          .icon-box {
            .gh-center();
            width: 115rpx;
            height: 115rpx;
            border-radius: 30rpx;
            background-color: #fff;
            .iconfont {
              font-size: 50rpx;
            }
          }
          .icon-text {
            margin-top: 15rpx;
            color: #7f7f7f;
            font-size: 26rpx;
            text-align: center;
          }
        }
      }
    }
  }
}
</style>